<?php

namespace app\middleware;

use app\model\OperationLog as OperationLogModel;
use think\Request;
use think\Response;

class OperationLog
{
    /**
     * 处理请求
     * @param Request $request
     * @param \Closure $next
     * @return Response
     */
    public function handle(Request $request, \Closure $next)
    {
        $startTime = microtime(true);
        
        // 获取用户信息
        $user = null;
        try {
            $user = $request->user;
        } catch (\Exception $e) {
            // 用户未登录或token无效
        }

        // 记录请求开始
        $logData = [
            'user_id' => $user ? $user->id : null,
            'username' => $user ? $user->username : 'guest',
            'action' => $this->getAction($request),
            'module' => $this->getModule($request),
            'description' => $this->getDescription($request),
            'request_method' => $request->method(),
            'request_url' => $request->url(true),
            'request_params' => $this->getRequestParams($request),
            'ip_address' => $request->ip(),
            'user_agent' => $request->header('user-agent'),
            'status' => 'success'
        ];

        // 执行请求
        $response = $next($request);
        
        // 计算执行时间
        $executionTime = microtime(true) - $startTime;
        
        // 更新日志数据
        $logData['execution_time'] = round($executionTime, 3);
        $logData['response_code'] = $response->getCode();
        
        // 获取响应信息
        $responseData = $response->getData();
        if (is_array($responseData)) {
            $logData['response_message'] = $responseData['message'] ?? '';
            if (isset($responseData['code']) && $responseData['code'] !== 200) {
                $logData['status'] = 'error';
            }
        }

        // 异步记录日志（避免影响响应速度）
        try {
            OperationLogModel::record($logData);
        } catch (\Exception $e) {
            // 记录失败不影响正常响应
            error_log('Operation log middleware error: ' . $e->getMessage());
        }

        return $response;
    }

    /**
     * 获取操作动作
     * @param Request $request
     * @return string
     */
    private function getAction(Request $request)
    {
        $path = $request->pathinfo();
        $method = $request->method();
        
        // 根据路径和方法判断操作
        $actionMap = [
            'auth/login' => '用户登录',
            'auth/logout' => '用户登出',
            'auth/profile' => '获取用户信息',
            'system-configs/external-api' => '更新系统配置',
            'system-configs/test-token' => '测试Token连接',
            'orders' => '订单管理',
            'import' => '数据导入',
            'settlement' => '结算管理',
            'insurance' => '保险管理',
            'purchase' => '采购管理',
            'reports' => '报表管理'
        ];

        foreach ($actionMap as $path => $action) {
            if (strpos($path, $path) !== false) {
                return $action;
            }
        }

        return $method . ' ' . $path;
    }

    /**
     * 获取操作模块
     * @param Request $request
     * @return string
     */
    private function getModule(Request $request)
    {
        $path = $request->pathinfo();
        
        $moduleMap = [
            'auth' => '用户认证',
            'system-configs' => '系统配置',
            'orders' => '订单管理',
            'import' => '数据导入',
            'settlement' => '结算管理',
            'insurance' => '保险管理',
            'purchase' => '采购管理',
            'reports' => '报表管理'
        ];

        foreach ($moduleMap as $key => $module) {
            if (strpos($path, $key) !== false) {
                return $module;
            }
        }

        return '其他';
    }

    /**
     * 获取操作描述
     * @param Request $request
     * @return string
     */
    private function getDescription(Request $request)
    {
        $path = $request->pathinfo();
        $method = $request->method();
        
        $descriptions = [
            'GET auth/profile' => '获取用户个人信息',
            'POST auth/login' => '用户登录系统',
            'POST auth/logout' => '用户退出系统',
            'GET system-configs/external-api' => '获取外部API配置',
            'PUT system-configs/external-api' => '更新外部API配置',
            'GET system-configs/test-token' => '测试Token连接状态',
            'GET orders' => '获取订单列表',
            'POST orders/import' => '导入订单数据',
            'GET import' => '查看导入记录',
            'POST import/upload' => '上传导入文件',
            'GET settlement' => '查看结算数据',
            'GET insurance' => '查看保险数据',
            'GET purchase' => '查看采购数据',
            'GET reports' => '查看报表数据'
        ];

        $key = $method . ' ' . $path;
        return $descriptions[$key] ?? $method . ' ' . $path;
    }

    /**
     * 获取请求参数
     * @param Request $request
     * @return string
     */
    private function getRequestParams(Request $request)
    {
        $params = [];
        
        // 获取GET参数
        $getParams = $request->get();
        if (!empty($getParams)) {
            $params['get'] = $getParams;
        }
        
        // 获取POST参数（排除敏感信息）
        $postParams = $request->post();
        if (!empty($postParams)) {
            // 过滤敏感信息
            $filteredParams = $this->filterSensitiveData($postParams);
            $params['post'] = $filteredParams;
        }
        
        return !empty($params) ? json_encode($params, JSON_UNESCAPED_UNICODE) : '';
    }

    /**
     * 过滤敏感数据
     * @param array $data
     * @return array
     */
    private function filterSensitiveData($data)
    {
        $sensitiveKeys = ['password', 'token', 'secret', 'key', 'auth'];
        
        foreach ($data as $key => $value) {
            if (is_array($value)) {
                $data[$key] = $this->filterSensitiveData($value);
            } else {
                foreach ($sensitiveKeys as $sensitiveKey) {
                    if (stripos($key, $sensitiveKey) !== false) {
                        $data[$key] = '***';
                        break;
                    }
                }
            }
        }
        
        return $data;
    }
} 